#pragma once

#include "BasicObject.h"
#include "Functions.h"

namespace BAA
{

	class PersonalityTraitMotivational:public BasicObject
	{
	public:
		PersonalityTraitMotivational(const std::string name):BasicObject(name)
		{

		}

		virtual void Create()
		{
			mDecayRate = 1;
			mSetPoint = 0.5;
			mValue = 0.5;
			mDesire = 0;
		}


		~PersonalityTraitMotivational()
		{

		}


		/************************************************************************/
		/* returns the current value of the motivational trait. Should not be used
			unless with specific reason. For the desire of the trait use the 
			GetMotivationalDesire()                                        */
		/************************************************************************/
		inline float Value() const{return mValue;}


		/************************************************************************/
		/* Sets the value of the emotion bypassing the activation/deactivation function.
		/* Should be used and is the not the standard update for the emotion. 
		/************************************************************************/
		inline void Value(float value){mValue = value;}

		/************************************************************************/
		/* gets the set point for the motivation. Defines where agent is most comfortable */
		/************************************************************************/
		inline float SetPoint() const { return mSetPoint; }


		/************************************************************************/
		/* Sets the set point for the motivation. Defines where agent is most comfortable */
		/************************************************************************/
		inline void SetPoint(float val) { mSetPoint = val; }

		/************************************************************************/
		/* Gets how strongly a trait will reduce as a function of the desire function and time*/
		/************************************************************************/
		inline float DecayRate() const { return mDecayRate; }


		/************************************************************************/
		/* Sets how strongly a trait will reduce as a function of the desire function and time*/
		/************************************************************************/
		inline void DecayRate(float val) { mDecayRate = val; }


		/************************************************************************/
		/* Desire only as accurate as last update.                                                                      */
		/************************************************************************/
		float Desire() const { return mDesire; }		

		/************************************************************************/
		/* UPDATE MUST OCCUR                                                                     */
		/************************************************************************/
		inline void Update(float elapsedTime)
		{
			mValue = mDecayFunction->calculate(mValue, mDecayRate*elapsedTime);
			mDesire = mDesireFunction->calculate(mSetPoint, mValue);
		}


		inline void ModifyValue(float amount)
		{
			mValue = mDecayFunction->calculate(mValue, amount);
			mDesire = mDesireFunction->calculate(mSetPoint, mValue);

		}


		inline void Clear()
		{
			mDecayRate = 1;
			mSetPoint = 0.5;
			mValue = 0.5;
		}

		inline void Initialize(float setPoint, float initialValue, float decayRate)
		{
			mSetPoint = setPoint;
			mValue = initialValue;
			mDecayRate = decayRate;

			mDesire = mDesireFunction->calculate(mSetPoint, mValue);
		}

		FunctionP2* DesireFunction()  { return mDesireFunction; }
		void DesireFunction(FunctionP2* val) { mDesireFunction = val; }

		FunctionP2* DecayFunction()  { return mDecayFunction; }
		void DecayFunction(FunctionP2* val) { mDecayFunction = val; }

	protected:

		float			mValue;
		float			mSetPoint;
		float			mDecayRate;
		float			mDesire;

		FunctionP2*     mDecayFunction;

		FunctionP2*		mDesireFunction;




	};// end class
}// end namespace